@h2loop/uav 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -16
- package/USAGE.md +47 -30
- package/bridge/requirements.txt +5 -1
- package/mcp.json +1 -7
- package/package.json +1 -1
- package/plugins/index.js +36 -36
- package/plugins/worker/worker-entry.js +5 -9
- package/skills/uav/SKILL.md +4 -1
- package/skills/uav/references/tuning.md +4 -2
package/README.md
CHANGED
|
@@ -59,7 +59,9 @@ skills/uav/ # on-demand `uav` skill + references
|
|
|
59
59
|
data/ # bundled apm-params.json + built-in defaults
|
|
60
60
|
bridge/ # optional MAVLink→MCP Python bridge
|
|
61
61
|
plugins/ # BUILT bundle (index.js + worker/) — generated
|
|
62
|
-
mcp.json # exa
|
|
62
|
+
mcp.json # exa MCP server (disabled by default); mavlink is registered
|
|
63
|
+
# from src/index.ts's config hook — it needs a resolved
|
|
64
|
+
# interpreter + an ABSOLUTE script path, which static JSON can't give
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
## Run standalone
|
|
@@ -235,30 +237,29 @@ project KG.
|
|
|
235
237
|
|
|
236
238
|
A local Python stdio server. Read-only tools: `read_params`, `param_get`, `param_get_all`,
|
|
237
239
|
`get_messages`, `tail_telemetry`, `get_flight_mode`, `get_status`. The write tier
|
|
238
|
-
(`param_set` / `param_set_batch`) is **
|
|
240
|
+
(`param_set` / `param_set_batch`) is **on by default** so tune→push→retest works out of the
|
|
241
|
+
box — see below.
|
|
239
242
|
|
|
240
243
|
**Requires:**
|
|
241
|
-
- Python ≥ 3.10 with `pymavlink>=2.4.49` and `mcp[cli]>=1.0.0` installed. The pack does **not**
|
|
244
|
+
- Python ≥ 3.10 with `pymavlink>=2.4.49` and `mcp[cli]>=1.0.0,<2` installed. The pack does **not**
|
|
242
245
|
auto-provision a venv — install the deps yourself: `pip install -r bridge/requirements.txt`
|
|
243
246
|
(ideally into a venv), and point the command's `python3` at that interpreter.
|
|
244
247
|
- A reachable MAVLink endpoint (e.g. `udp:127.0.0.1:14550` from SITL or a telemetry radio),
|
|
245
248
|
or a `.tlog`/`.log` file for offline replay.
|
|
246
249
|
- The `bridge/` directory ships with the plugin (the `mcp.json` references it).
|
|
247
250
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
"--connect", "udp:127.0.0.1:14550",
|
|
258
|
-
"--no-read-only", "--allow-param-write"]
|
|
259
|
-
}
|
|
260
|
-
}
|
|
251
|
+
Ships **enabled**, with param writes **on** — the command passes `--no-read-only`
|
|
252
|
+
`--allow-param-write`, so `param_set` / `param_set_batch` are registered and the tuning loop
|
|
253
|
+
works with no configuration. ⚠ this lets the agent write params to a **live vehicle** — prefer
|
|
254
|
+
SITL/bench. To ship read-only, drop both flags.
|
|
255
|
+
|
|
256
|
+
No `--connect` is passed, so the target comes from the **`MAVLINK_CONNECT`** env var, falling
|
|
257
|
+
back to `udp:127.0.0.1:14550`:
|
|
258
|
+
```bash
|
|
259
|
+
export MAVLINK_CONNECT=serial:/dev/ttyUSB0:57600 # COM3:57600 on Windows
|
|
261
260
|
```
|
|
261
|
+
Don't put it in the server's `environment` block — Hydron spreads that *over* `process.env`, so
|
|
262
|
+
it would shadow your export instead of defaulting to it.
|
|
262
263
|
|
|
263
264
|
Connect-target forms: `udp:HOST:PORT` (default `udp:127.0.0.1:14550` = SITL/MAVProxy) |
|
|
264
265
|
`tcp:HOST:PORT` | `serial:/dev/ttyUSB0:BAUD` | `/path/log.tlog` (offline replay); can also be
|
package/USAGE.md
CHANGED
|
@@ -12,7 +12,7 @@ covers getting it running on **macOS, Linux, and Windows**, validating it works,
|
|
|
12
12
|
- **Bun** — *only* needed to build the bundle from source or run the pack's tests; **not**
|
|
13
13
|
needed to use a published pack.
|
|
14
14
|
- **Python ≥ 3.10** — *only* for the optional live MAVLink bridge (`pymavlink>=2.4.49` +
|
|
15
|
-
`mcp[cli]>=1.0.0`). The pack does **not** auto-provision a venv; you install the deps
|
|
15
|
+
`mcp[cli]>=1.0.0,<2`). The pack does **not** auto-provision a venv; you install the deps
|
|
16
16
|
yourself (see §6). Plain `.bin` log analysis needs no Python.
|
|
17
17
|
- *Optional:* `export EXA_API_KEY=…` for web grounding of bounds.
|
|
18
18
|
- **macOS, Linux, and Windows are all native** — no WSL required. The pack resolves the Python
|
|
@@ -127,50 +127,67 @@ See `skills/uav/references/project-config.md` for the full list (`uav-thresholds
|
|
|
127
127
|
A **MAVLink→MCP bridge**: a local Python stdio server Hydron spawns so the agent can query a
|
|
128
128
|
live vehicle / SITL / log replay. Read-only tools: `get_status`, `get_flight_mode`,
|
|
129
129
|
`read_params`, `param_get`, `param_get_all`, `get_messages`, `tail_telemetry`. The **write**
|
|
130
|
-
tools `param_set`/`param_set_batch` are **
|
|
130
|
+
tools `param_set`/`param_set_batch` are **on by default**, so tune→push→retest works out of
|
|
131
|
+
the box (see the ⚠ note below to turn them off).
|
|
131
132
|
|
|
132
|
-
### Install the Python deps
|
|
133
|
+
### Install the Python deps (the only manual step)
|
|
133
134
|
The pack does **not** auto-provision a venv. The bridge needs Python ≥ 3.10 with
|
|
134
|
-
`pymavlink>=2.4.49` and `mcp[cli]>=1.0.0`:
|
|
135
|
+
`pymavlink>=2.4.49` and `mcp[cli]>=1.0.0,<2`:
|
|
135
136
|
```bash
|
|
136
137
|
pip install -r bridge/requirements.txt # ideally into a venv
|
|
137
138
|
```
|
|
138
|
-
|
|
139
|
-
the
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
139
|
+
> The `<2` bound is required, not cosmetic: the MCP Python SDK **removed `mcp.server.fastmcp`
|
|
140
|
+
> in 2.x**, so the bridge fails at import on `mcp>=2`. Verified working on 1.29.0.
|
|
141
|
+
|
|
142
|
+
You do **not** need to edit any command. The plugin registers the `mavlink` server itself at
|
|
143
|
+
startup, resolving:
|
|
144
|
+
|
|
145
|
+
- **the interpreter** — via the same probe-by-execution resolver the `.tlog`/`.ulog` decoders
|
|
146
|
+
use, so `python3` / `python` / the Windows `py -3` launcher are all handled and Windows'
|
|
147
|
+
Microsoft-Store alias stubs are rejected. Pin a specific one with `UAV_PYTHON` (e.g. a venv:
|
|
148
|
+
`export UAV_PYTHON=/path/.venv/bin/python`, or `…\Scripts\python.exe` on Windows).
|
|
149
|
+
- **the script path** — absolute, inside the installed plugin bundle. This matters: Hydron
|
|
150
|
+
spawns local MCP servers with the cwd set to *your project*, so a bundle-relative path can
|
|
151
|
+
never resolve. That is why the server is no longer declared in `mcp.json`.
|
|
152
|
+
|
|
153
|
+
If no usable Python is found the server is not registered at all; if Python is found but can't
|
|
154
|
+
`import mcp, pymavlink`, it is registered **disabled** — so you see it listed rather than
|
|
155
|
+
getting a failed server on every launch. Check with `hydron mcp list`.
|
|
156
|
+
|
|
157
|
+
### Point it at your vehicle
|
|
158
|
+
The `mavlink` server is registered **enabled**, with param writes on, so nothing needs enabling.
|
|
159
|
+
The one thing you may need to change is the connect target.
|
|
160
|
+
|
|
161
|
+
The command passes **no** `--connect`, so the bridge falls back to its own default —
|
|
162
|
+
which reads the **`MAVLINK_CONNECT`** environment variable, then `udp:127.0.0.1:14550`. So for
|
|
163
|
+
anything other than local SITL/MAVProxy, just export the target:
|
|
164
|
+
```bash
|
|
165
|
+
export MAVLINK_CONNECT=serial:/dev/ttyUSB0:57600 # or COM3:57600 on Windows
|
|
153
166
|
```
|
|
154
167
|
Connect-target forms: `udp:HOST:PORT` (default `udp:127.0.0.1:14550` = SITL/MAVProxy) |
|
|
155
168
|
`tcp:HOST:PORT` | `serial:/dev/ttyUSB0:BAUD` (on Windows a COM port, e.g. `COM3` or
|
|
156
|
-
`COM3:57600`) | `/path/log.tlog` (offline replay).
|
|
157
|
-
|
|
169
|
+
`COM3:57600`) | `/path/log.tlog` (offline replay).
|
|
170
|
+
|
|
171
|
+
> Set it in the environment, **not** in the server's `environment` block: Hydron spawns local
|
|
172
|
+
> MCP servers with `{...process.env, ...environment}`, so a server-level entry *shadows* your
|
|
173
|
+
> export rather than acting as a default. That is why the plugin sets neither.
|
|
158
174
|
|
|
159
175
|
> **"Connected" ≠ a live vehicle.** The panel shows `mavlink Connected` once the bridge *process*
|
|
160
176
|
> starts. The tools only return data while something is **actually publishing MAVLink** at the
|
|
161
177
|
> connect target. With no source, calls return empty / time out (`-32001`). Start your SITL/vehicle
|
|
162
178
|
> (or leave it — log analysis via `uav_analyze` doesn't need the live bridge).
|
|
163
179
|
|
|
164
|
-
>
|
|
165
|
-
> tune→push→retest write tier (`param_set` /
|
|
166
|
-
>
|
|
167
|
-
>
|
|
168
|
-
>
|
|
169
|
-
>
|
|
170
|
-
>
|
|
180
|
+
> **⚠ Param writes are ON by default.** The shipped command passes `--no-read-only`
|
|
181
|
+
> `--allow-param-write`, which registers the tune→push→retest write tier (`param_set` /
|
|
182
|
+
> `param_set_batch`). This lets the agent **write parameters to a live vehicle**. Prefer
|
|
183
|
+
> SITL/bench, and point `MAVLINK_CONNECT` at a real airframe only when you intend that.
|
|
184
|
+
>
|
|
185
|
+
> To ship read-only, remove both flags from the `config` hook in `src/index.ts` — the bridge's own defaults are
|
|
186
|
+
> `read_only=True` / `allow_param_write=False`, and the write tools are then never registered:
|
|
187
|
+
> ```ts
|
|
188
|
+
> command: [...py, script], // no --no-read-only / --allow-param-write
|
|
171
189
|
> ```
|
|
172
|
-
>
|
|
173
|
-
> `--connect` at a real airframe only when you intend that.
|
|
190
|
+
> Reads (`param_get`, `param_get_all`, `read_params`, telemetry) are unaffected either way.
|
|
174
191
|
|
|
175
192
|
---
|
|
176
193
|
|
package/bridge/requirements.txt
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
pymavlink>=2.4.49
|
|
2
|
-
|
|
2
|
+
# Pinned below 2.0: the MCP Python SDK removed `mcp.server.fastmcp` in 2.x (FastMCP is gone,
|
|
3
|
+
# replaced by a different MCPServer API), so this bridge fails at import on mcp>=2. The
|
|
4
|
+
# unpinned `>=1.0.0` silently floated into that breaking major. Porting to the 2.x server API
|
|
5
|
+
# is a separate change; until then this range is the supported one (verified on 1.29.0).
|
|
6
|
+
mcp[cli]>=1.0.0,<2
|
package/mcp.json
CHANGED
|
@@ -4,12 +4,6 @@
|
|
|
4
4
|
"url": "https://mcp.exa.ai/mcp",
|
|
5
5
|
"headers": { "x-api-key": "${EXA_API_KEY}" },
|
|
6
6
|
"enabled": false
|
|
7
|
-
},
|
|
8
|
-
"mavlink": {
|
|
9
|
-
"type": "local",
|
|
10
|
-
"enabled": false,
|
|
11
|
-
"command": ["python3", "./bridge/uav_mavlink_bridge.py", "--connect", "udp:127.0.0.1:14550"],
|
|
12
|
-
"environment": { "MAVLINK_DIALECT": "ardupilotmega" },
|
|
13
|
-
"timeout": 10000
|
|
14
7
|
}
|
|
15
8
|
}
|
|
9
|
+
|